package com.wms.plugin;

import com.alibaba.druid.util.Base64;
import io.jsonwebtoken.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Date;

@Component
public class JwtPlugin {

    private final String JWT_SECERT = "d21z";
    private byte[] encodedKey = Base64.base64ToByteArray(JWT_SECERT);

    private Logger log = LoggerFactory.getLogger(JwtPlugin.class);

    /**
     * 签发JWT
     * @param id
     * @param subject 可以是JSON数据 尽可能少
     * @param ttlMillis 过期时间
     * @return  String
     *
     */
    public String createJWT(String id, String subject, long ttlMillis) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        SecretKey secretKey = generalKey();
        JwtBuilder builder = Jwts.builder()
                .setId(id)
                .setSubject(subject)   // 主题
                .setIssuer("user")     // 签发者
                .setIssuedAt(now)      // 签发时间
                .signWith(signatureAlgorithm, secretKey); // 签名算法以及密匙
        if (ttlMillis >= 0) {
            long expMillis = nowMillis + ttlMillis;
            Date expDate = new Date(expMillis);
            builder.setExpiration(expDate); // 过期时间
        }
        return builder.compact();
    }

    /**
     * 验证JWT
     * @param jwtStr
     * @return
     */
    public boolean validateJWT(String jwtStr) {
        Claims claims = parseJWT(jwtStr);
        return claims != null && claims.getExpiration().after(new Date());
    }

    /**
     * 解析jwt
     * @param jsonWebToken
     * @return
     */
    public Claims parseJWT(String jsonWebToken) {
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(encodedKey)
                    .parseClaimsJws(jsonWebToken).getBody();
            return claims;
        } catch (ExpiredJwtException  e) {
            log.error("===== Token[{}]过期,e:{} =====", jsonWebToken, e);
        } catch (Exception e){
            log.error("===== token[{}]解析异常,e:{} =====", jsonWebToken, e);
        }
        return null;
    }

    public SecretKey generalKey() {
        return new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
    }

}
